Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-0 vector-toc-not-available vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-0 vector-feature-night-mode-enabled skin-theme-clientpref-os vector-sticky-header-enabled" lang="fr" dir="ltr"><head>
<meta charset="UTF-8">
<title>Portable Executable</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./_res_/favicon.png">
<link rel="canonical" href="https://fr.wikipedia.org/wiki/Portable_Executable"> <link href="./_mw_/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.wikimediamessages.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./_mw_/site.styles.css">
<link rel="stylesheet" type="text/css" href="./_mw_/noscript.css">
<link rel="stylesheet" type="text/css" href="./_res_/footer.css">
<link rel="stylesheet" type="text/css" href="./_res_/vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Portable_Executable rootpage-Portable_Executable skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-main">Portable Executable</span></h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="contentSub">
<div id="mw-content-subtitle"></div>
</div>
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="fr" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="fr" dir="ltr">

<div class="infobox_v3 infobox infobox--frwiki noarchive large"><div class="entete icon informatique" style="background-color:#C0C0C0"><div>Portable Executable<style data-mw-deduplicate="TemplateStyles:r228712691">
/* start https://fr.wikipedia.org/ */


.mw-parser-output .entete.informatique{background-image:url("./_mw_/Picto.nfo.png")}


/* end https://fr.wikipedia.org/ */
</style></div></div><div><div class="images" style="padding:2px 0"></div><div class="legend">Visualisation du début d'un fichier PE avec WinHex</div></div><table><caption style="text-align:center;background-color:#C0C0C0">Caractéristiques</caption><tbody><tr class=""><th scope="row"><a href="Extension_de_nom_de_fichier" title="Extension de nom de fichier">Extension</a></th><td class=""><div>
<tt>.cpl</tt>, <tt>.exe</tt>, <tt>.dll</tt>, <tt>.ocx</tt>, <tt>.sys</tt>, <tt>.scr</tt>, <tt>.drv</tt>, <tt>.efi</tt></div></td></tr><tr class=""><th scope="row"><a href="Type_de_m%C3%A9dias" title="Type de médias">Type MIME</a></th><td class=""><div>
<span class="wd_p1163"><code> application/vnd.microsoft.portable-executable</code>, <code> application/efi</code></span></div></td></tr><tr class=""><th scope="row"><a href="Base_PRONOM" title="Base PRONOM">PUID</a></th><td class=""><div>
<span class="wd_p2748"><a rel="nofollow" class="external text" href="https://www.nationalarchives.gov.uk/pronom/x-fmt/411">x-fmt/411</a></span></div></td></tr><tr class=""><th scope="row"><a href="Nombre_magique_(programmation)" title="Nombre magique (programmation)">Signatures</a></th><td class=""><div>
<span class="wd_p4152"><code>4D 5A</code> (<a href="Syst%C3%A8me_hexad%C3%A9cimal" title="Système hexadécimal">hexa</a>)<br><code>4D5A*50450000</code> (<a href="Base_PRONOM" title="Base PRONOM">PRONOM</a> <a href="Expression_r%C3%A9guli%C3%A8re" title="Expression régulière">regex</a>)</span></div></td></tr><tr class=""><th scope="row">Type de format</th><td class=""><div>
<a href="Fichier_binaire" title="Fichier binaire">Binaire</a>, <a href="Fichier_ex%C3%A9cutable" title="Fichier exécutable">Exécutable</a>, <a href="Code_objet" title="Code objet">Code Objet</a>, <a href="Biblioth%C3%A8que_logicielle" title="Bibliothèque logicielle">DLL</a></div></td></tr><tr class=""><th scope="row">Basé sur</th><td class=""><div>
<a href="Ex%C3%A9cutable_MZ_(MS-DOS)" title="Exécutable MZ (MS-DOS)">Exécutable MZ</a><br><a href="Common_Object_File_Format" title="Common Object File Format">COFF</a></div></td></tr></tbody></table></div>
<p><b><span class="lang-en" lang="en">Portable Executable</span></b> (en français "<i>exécutable portable"</i>) est un <a href="Format_de_donn%C3%A9es" title="Format de données">format de fichiers</a> dérivé du <a href="Common_Object_File_Format" title="Common Object File Format">COFF</a> regroupant les <a href="Fichier_ex%C3%A9cutable" title="Fichier exécutable">exécutables</a> et les <a href="Biblioth%C3%A8que_logicielle" title="Bibliothèque logicielle">bibliothèques</a> sur les <a href="Syst%C3%A8me_d'exploitation" title="Système d'exploitation">systèmes d'exploitation</a> <a href="Microsoft_Windows" title="Microsoft Windows">Windows</a> 32 bits et <a href="Processeur_64_bits" title="Processeur 64 bits">64 bits</a>.
</p><p>Les extensions couvertes par ce format sont&nbsp;: l'extension <a href=".exe" title=".exe">.exe</a>, l'extension .ocx (<a href="Object_Linking_and_Embedding" title="Object Linking and Embedding">OLE</a> et <a href="ActiveX" title="ActiveX">ActiveX</a>), l'extension <a href="Dynamic_Link_Library" title="Dynamic Link Library">.dll</a> et l'extension <a href=".cpl" class="mw-redirect" title=".cpl">.cpl</a>.
</p><p>C'est également le format utilisé pour les exécutables de l'<a href="Unified_Extensible_Firmware_Interface" class="mw-redirect" title="Unified Extensible Firmware Interface">UEFI</a> (.efi).
</p><p>Portable Executable est souvent abrégé par PE.
</p>

<div class="mw-heading mw-heading2"><h2 id="Historique">Historique</h2></div>
<p>Microsoft a adopté le format PE avec l'introduction de <a href="Windows_NT_3.1" title="Windows NT 3.1">Windows NT 3.1</a>. Toutes les versions suivantes de Windows, incluant Windows 10/11, supportent ce format. Auparavant les fichiers «exécutables» étaient au format NE — <i><a href="New_Executable" title="New Executable">New Executable File Format</a></i>, «&nbsp;<i>New</i>&nbsp;» faisant référence à <a href="CP/M" class="mw-redirect" title="CP/M">CP/M</a>, et aux fichiers <a href=".com_(MS-DOS)" title=".com (MS-DOS)">*.com</a> —.
</p><p>La création du format PE a été induite par la volonté de Microsoft de concevoir une structure de fichier qui puisse s'adapter aux différentes machines utilisant Windows NT, lequel était initialement capable de supporter d'autres architectures que le <a href="X86" title="X86">x86</a> d'Intel (<a href="PowerPC" title="PowerPC">Power PC</a> et <a href="Motorola_68000" title="Motorola 68000">Motorola 68000</a> par exemple). L'idée fut donc de créer une structure comme ces <a href="Architecture_(informatique)" title="Architecture (informatique)">architectures</a>.
</p>
<div class="mw-heading mw-heading2"><h2 id="Schéma_du_format_PE"><span id="Sch.C3.A9ma_du_format_PE"></span>Schéma du format PE</h2></div>
<p>Un fichier exécutable PE est structuré de la façon suivante&nbsp;:<span typeof="mw:File"></span>
</p><p>Les deux premiers octets du fichier représentent les caractères MZ.
</p>
<div class="mw-heading mw-heading3"><h3 id="En-tête_MZ_sous_MS-DOS"><span id="En-t.C3.AAte_MZ_sous_MS-DOS"></span>En-tête MZ sous MS-DOS</h3></div>
<p>L'en-tête MZ permet au <a href="Syst%C3%A8me_d'exploitation" title="Système d'exploitation">système d'exploitation</a> de reconnaître le fichier comme étant un exécutable valide dans le cas où celui-ci serait lancé depuis <a href="MS-DOS" title="MS-DOS">MS-DOS</a>, afin de pouvoir exécuter son segment DOS.
</p><p>Voici la structure de l'en-tête, en <a href="C_(langage)" title="C (langage)">langage C</a>&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_DOS_HEADER</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// DOS .EXE header</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_magic</span><span class="p">;</span><span class="w"> </span><span class="c1">// Magic number</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_cblp</span><span class="p">;</span><span class="w"> </span><span class="c1">// Bytes on last page of file</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_cp</span><span class="p">;</span><span class="w"> </span><span class="c1">// Pages in file</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_crlc</span><span class="p">;</span><span class="w"> </span><span class="c1">// Relocations</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_cparhdr</span><span class="p">;</span><span class="w"> </span><span class="c1">// Size of header in paragraphs</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_minalloc</span><span class="p">;</span><span class="w"> </span><span class="c1">// Minimum extra paragraphs needed</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_maxalloc</span><span class="p">;</span><span class="w"> </span><span class="c1">// Maximum extra paragraphs needed</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_ss</span><span class="p">;</span><span class="w"> </span><span class="c1">// Initial (relative) SS value</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_sp</span><span class="p">;</span><span class="w"> </span><span class="c1">// Initial SP value</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_csum</span><span class="p">;</span><span class="w"> </span><span class="c1">// Checksum</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_ip</span><span class="p">;</span><span class="w"> </span><span class="c1">// Initial IP value</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_cs</span><span class="p">;</span><span class="w"> </span><span class="c1">// Initial (relative) CS value</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_lfarlc</span><span class="p">;</span><span class="w"> </span><span class="c1">// File address of relocation table</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_ovno</span><span class="p">;</span><span class="w"> </span><span class="c1">// Overlay number</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_res</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span><span class="w"> </span><span class="c1">// Reserved words</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_oemid</span><span class="p">;</span><span class="w"> </span><span class="c1">// OEM identifier (for e_oeminfo)</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_oeminfo</span><span class="p">;</span><span class="w"> </span><span class="c1">// OEM information; e_oemid specific</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">e_res2</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span><span class="w"> </span><span class="c1">// Reserved words</span>
<span class="w"> </span><span class="n">LONG</span><span class="w"> </span><span class="n">e_lfanew</span><span class="p">;</span><span class="w"> </span><span class="c1">// File address of new exe header</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="n">IMAGE_DOS_HEADER</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_DOS_HEADER</span><span class="p">;</span>
</pre></div>
<p>On reconnaît par exemple&nbsp;:
</p>
<ul><li>e_magic qui doit valoir "MZ"</li>
<li>e_lfanew qui contient l'adresse du début de l'en-tête PE</li></ul>
<div class="mw-heading mw-heading3"><h3 id="Segment_DOS">Segment DOS</h3></div>
<p>Le segment DOS est exécuté lorsque Windows ne reconnaît pas le fichier comme étant au format PE, ou s'il est exécuté sous <a href="MS-DOS" title="MS-DOS">MS-DOS</a>. Il affiche en général un message comme <i>This program cannot be run in DOS mode</i>, littéralement traduit, <i>Ce programme ne peut pas être exécuté en mode DOS</i>.
</p>
<div class="mw-heading mw-heading3"><h3 id="En-tête_PE"><span id="En-t.C3.AAte_PE"></span>En-tête PE</h3></div>
<p>L'en-tête PE est un ensemble de <a href="Structure_de_donn%C3%A9es" title="Structure de données">structures</a>, regroupées dans une même et unique structure nommée IMAGE_NT_HEADER. Voici son prototype en langage <a href="C_(langage)" title="C (langage)">C</a>&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_NT_HEADERS</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Signature</span><span class="p">;</span>
<span class="w"> </span><span class="n">IMAGE_FILE_HEADER</span><span class="w"> </span><span class="n">FileHeader</span><span class="p">;</span>
<span class="w"> </span><span class="n">IMAGE_OPTIONAL_HEADER</span><span class="w"> </span><span class="n">OptionalHeader</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_NT_HEADERS</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_NT_HEADERS</span><span class="p">;</span>
</pre></div>
<ul><li>Signature permettant d'identifier le fichier, qui doit être égale à <i>0x00004550</i>, soit "PE\0\0" (\0 étant un octet nul).</li></ul>
<ul><li>FileHeader est une <a href="Structure_de_donn%C3%A9es" title="Structure de données">structure</a> nommée IMAGE_FILE_HEADER contenant des informations sur la structuration du fichier, et prototypée comme suit&nbsp;:</li></ul>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_FILE_HEADER</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">Machine</span><span class="p">;</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">NumberOfSections</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">TimeDateStamp</span><span class="p">;</span><span class="w"> </span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">PointerToSymbolTable</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">NumberOfSymbols</span><span class="p">;</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">SizeOfOptionalHeader</span><span class="p">;</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">Characteristics</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_FILE_HEADER</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_FILE_HEADER</span><span class="p">;</span>
</pre></div>
<p>Voir <abbr class="abbr indicateur-langue" title="Langue : anglais">(en)</abbr> <a rel="nofollow" class="external free" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx</a>
</p>
<ul><li>OptionalHeader est une <a href="Structure_de_donn%C3%A9es" title="Structure de données">structure</a> nommée IMAGE_OPTIONAL_HEADER</li></ul>
<p>Voir <abbr class="abbr indicateur-langue" title="Langue : anglais">(en)</abbr> <a rel="nofollow" class="external free" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339%28v=vs.85%29.aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339%28v=vs.85%29.aspx</a> pour plus de détails
</p>
<div class="mw-heading mw-heading4"><h4 id="Adresses_physique,_virtuelle_et_mémoire"><span id="Adresses_physique.2C_virtuelle_et_m.C3.A9moire"></span>Adresses physique, virtuelle et mémoire</h4></div>
<p>La première chose à savoir est que l'exécutable est chargé en mémoire à l'adresse ImageBase (présent dans OptionalHeader) si cette adresse est disponible. Sinon il est chargé à une autre adresse qui sera la nouvelle valeur ImageBase.
</p><p>Dans l'en-tête et le corps d'un fichier PE, on trouve trois adressages différents&nbsp;:
</p>
<ul><li>Les adresses physiques représentent une position dans le fichier. Dans l'en-tête, leur nom commence par PointerTo</li>
<li>Les adresses virtuelles indiquent une position en mémoire relative à ImageBase. Dans l'en-tête, leur nom commence par Virtual</li>
<li>Les adresses mémoire sont aussi une position en mémoire mais cette fois absolue, ces adresses sont le plus souvent présentes dans le code de l'application et les données mais pas dans les en-têtes. Dans le cas où ImageBase a été modifié, la table des relocalisations indique la position des adresses mémoire à rectifier.</li></ul>
<div class="mw-heading mw-heading4"><h4 id="Répertoires"><span id="R.C3.A9pertoires"></span>Répertoires</h4></div>
<p>Les répertoires sont des parties du fichier utilisées lors de son chargement.
</p><p>La position et la taille des données de ces répertoires sont indiquées dans le champ DataDirectory de OptionalHeader qui est un tableau de structures IMAGE_DATA_DIRECTORY décrit comme suit&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_DATA_DIRECTORY</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">VirtualAddress</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Size</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_DATA_DIRECTORY</span><span class="p">,</span><span class="o">*</span><span class="n">PIMAGE_DATA_DIRECTORY</span><span class="p">;</span>
</pre></div>
<p>VirtualAddress étant l'adresse du début du contenu du répertoire une fois les sections chargées en mémoire, relative à ImageBase (présent dans OptionalHeader).
</p><p>Et Size sa taille.
</p><p>Bien que le champ NumberOfRvaAndSizes de OptionalHeader indique leur nombre, il y en a habituellement 16&nbsp;:
</p>
<table class="wikitable" style="text-align:center; width:65%;">

<tbody><tr>
<td>Position
</td>
<td>Nom
</td>
<td>Description
</td></tr>
<tr>
<td>0
</td>
<td>IMAGE_DIRECTORY_ENTRY_EXPORT
</td>
<td>Table des exports
</td></tr>
<tr>
<td>1
</td>
<td>IMAGE_DIRECTORY_ENTRY_IMPORT
</td>
<td>Table des imports
</td></tr>
<tr>
<td>2
</td>
<td>IMAGE_DIRECTORY_ENTRY_RESOURCE
</td>
<td>Table des ressources
</td></tr>
<tr>
<td>3
</td>
<td>IMAGE_DIRECTORY_ENTRY_EXCEPTION
</td>
<td>Table des exceptions
</td></tr>
<tr>
<td>4
</td>
<td>IMAGE_DIRECTORY_ENTRY_SECURITY
</td>
<td>Table des certificats
</td></tr>
<tr>
<td>5
</td>
<td>IMAGE_DIRECTORY_ENTRY_BASERELOC
</td>
<td>Table des relocalisations
</td></tr>
<tr>
<td>6
</td>
<td>IMAGE_DIRECTORY_ENTRY_DEBUG
</td>
<td>Informations de débogage
</td></tr>
<tr>
<td>7
</td>
<td>IMAGE_DIRECTORY_ENTRY_COPYRIGHT / IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
</td>
<td>Données spécifiques aux droits de copies ou à l'architecture
</td></tr>
<tr>
<td>8
</td>
<td>IMAGE_DIRECTORY_ENTRY_GLOBALPTR
</td>
<td>pointeurs globaux
</td></tr>
<tr>
<td>9
</td>
<td>IMAGE_DIRECTORY_ENTRY_TLS
</td>
<td>Table de stockage des threads locaux (TLS (Thread local storage) table en anglais)
</td></tr>
<tr>
<td>10
</td>
<td>IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
</td>
<td>Load configuration table
</td></tr>
<tr>
<td>11
</td>
<td>IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
</td>
<td>Table des imports liés
</td></tr>
<tr>
<td>12
</td>
<td>IMAGE_DIRECTORY_ENTRY_IAT
</td>
<td>Table des adresses des imports
</td></tr>
<tr>
<td>13
</td>
<td>IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
</td>
<td>Descripteur des imports en différé
</td></tr>
<tr>
<td>14
</td>
<td>IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
</td>
<td>en-tête runtime COM+
</td></tr>
<tr>
<td>15
</td>
<td>-
</td>
<td>réservé: doit être vide.
</td></tr>
</tbody></table>
<div class="mw-heading mw-heading3"><h3 id="Table_des_sections">Table des sections</h3></div>

<p>La Table des Sections est située juste derrière l'en-tête PE. Il s'agit d'un <a href="Tableau_(structure_de_donn%C3%A9es)" title="Tableau (structure de données)">tableau</a> contenant plusieurs <a href="Structure_de_donn%C3%A9es" title="Structure de données">structures</a> IMAGE_SECTION_HEADER.
</p><p>Ces structures contiennent les informations sur les sections du binaire devant être chargé en mémoire.
</p><p>Le champ NumberOfSections de la structure IMAGE_FILE_HEADER indique combien d'entrées il y a dans cette table. Le maximum supporté par Windows est de 96 sections.
</p><p>La Table des Sections est prototypé comme suit&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_SECTION_HEADER</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">BYTE</span><span class="w"> </span><span class="n">Name</span><span class="p">[</span><span class="n">IMAGE_SIZEOF_SHORT_NAME</span><span class="p">];</span>
<span class="w"> </span><span class="k">union</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">PhysicalAddress</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">VirtualSize</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="n">Misc</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">VirtualAddress</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">SizeOfRawData</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">PointerToRawData</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">PointerToRelocations</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">PointerToLinenumbers</span><span class="p">;</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">NumberOfRelocations</span><span class="p">;</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">NumberOfLinenumbers</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Characteristics</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_SECTION_HEADER</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_SECTION_HEADER</span><span class="p">;</span>
</pre></div>
<p>Chaque section a un nom de 8 caractères, ce nom n'est pas significatif mais on peut généralement trouver les suivants&nbsp;:
</p>
<table class="wikitable" style="text-align:center; width:65%;">

<tbody><tr>
<td>Nom
</td>
<td>Description
</td></tr>
<tr>
<td>.text
</td>
<td>Le code (instructions) du programme
</td></tr>
<tr>
<td>.bss
</td>
<td>Les variables non-initialisées
</td></tr>
<tr>
<td>.reloc
</td>
<td>La table des relocalisations (le sixième répertoire)
</td></tr>
<tr>
<td>.data
</td>
<td>Les variables initialisées
</td></tr>
<tr>
<td>.rsrc
</td>
<td>Les ressources du fichier (le troisième répertoire: Curseurs, Sons, Menus…)
</td></tr>
<tr>
<td>.rdata
</td>
<td>Les données en lectures seule
</td></tr>
<tr>
<td>.idata
</td>
<td>La table d'import (le second répertoire)
</td></tr>
<tr>
<td>.upx
</td>
<td>Signe d'une compression UPX, propre au logiciel UPX
</td></tr>

<tr>
<td>.aspack
</td>
<td>Signe d'un package ASPACK, propre au logiciel ASPACK
</td></tr>

<tr>
<td>.adata
</td>
<td>Signe d'un package ASPACK, propre au logiciel ASPACK
</td></tr>
</tbody></table>
<div class="mw-heading mw-heading3"><h3 id="Table_des_relocalisations">Table des relocalisations</h3></div>
<p>La table des relocalisations est présente dans le sixième répertoire 'Base relocation table'. Elle indique les adresses virtuelles des valeurs représentant une adresse mémoire. Elle permet, dans le cas où l'exécutable n'a pas été chargé en mémoire à l'adresse ImageBase, de replacer toutes les références mémoire pour correspondre à la nouvelle valeur ImageBase.
</p><p>La table des relocalisations est une suite de structures de tailles variables. Chacune est composée d'un en-tête de type IMAGE_BASE_RELOCATION puis d'un tableau de valeurs de type WORD (de taille 16 bits). Il arrive parfois que la dernière valeur soit 0, dans ce cas elle ne sert que pour l'alignement sur 4&nbsp;octets.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_BASE_RELOCATION</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">VirtualAddress</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">SizeOfBlock</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_BASE_RELOCATION</span><span class="p">,</span><span class="o">*</span><span class="n">PIMAGE_BASE_RELOCATION</span><span class="p">;</span>
</pre></div>
<ul><li>SizeOfBlock est la taille en octets de la structure, en-tête compris.</li>
<li>VirtualAddress est l'adresse virtuelle (relative à ImageBase) de base pour les valeurs</li></ul>
<p>On ne connait pas le nombre de structures présentes dans la table des relocalisations, mais on sait sa taille et donc on s'arrête lorsque l'on a atteint la fin. De même on ne sait pas combien de valeurs suivent chaque en-tête, mais on le déduit de la taille.
</p><p>Chaque valeur est composée de 4 bits d'informations et de 12 bits de données.
</p><p>La partie information peut être l'une de ces valeurs&nbsp;:
</p>
<table>

<tbody><tr>
<td>Valeur
</td>
<td>Description
</td></tr>
<tr>
<td>IMAGE_REL_BASED_ABSOLUTE
</td>
<td>
</td></tr>
<tr>
<td>IMAGE_REL_BASED_HIGH
</td>
<td>
</td></tr>
<tr>
<td>IMAGE_REL_BASED_LOW
</td>
<td>
</td></tr>
<tr>
<td>IMAGE_REL_BASED_HIGHLOW
</td>
<td>La donnée est une adresse relative à la base (adresse virtuelle = VirtualAddress + donnée)
</td></tr>
<tr>
<td>IMAGE_REL_BASED_HIGHADJ
</td>
<td>
</td></tr>
<tr>
<td>IMAGE_REL_BASED_MIPS_JMPADDR
</td>
<td>
</td></tr>
</tbody></table>
<p>Le plus souvent seul IMAGE_REL_BASED_HIGHLOW est utilisé.
</p><p>La valeur de l'adresse mémoire ainsi calculée sera décalée selon la différence entre l'ImageBase d'origine et l'adresse du début de la mémoire allouée au programme.
</p>
<div class="mw-heading mw-heading3"><h3 id="Table_d'import_-_IAT"><span id="Table_d.27import_-_IAT"></span>Table d'import - IAT</h3></div>

<p>L'IAT, qui signifie import address table, contenue dans le second répertoire import table (généralement dans la section .idata ou .rdata), indique les adresses des <a href="Interface_de_programmation" title="Interface de programmation">API</a> importées par un logiciel, ainsi que les noms des DLL important ces fonctions. Les API, contenues dans ces <a href="Dynamic_Link_Library" title="Dynamic Link Library">DLL</a>, permettent aux logiciels de fonctionner correctement.
</p><p>Son existence est due au fait que les API sont adressées différemment en fonction des OS.
</p><p>Il faut savoir en premier lieu qu'une structure nommée IMAGE_IMPORT_DESCRIPTOR est utilisée pour chaque DLL appelée; plus une dernière de 5 DWORD mis à zéro qui définit une terminaison.
</p><p>Pour chaque DLL importée, une structure nommée IMAGE_THUNK_DATA sera utilisée pour chaque API de cette DLL&nbsp;; il y aura donc autant de IMAGE_THUNK_DATA que de fonctions exportées par une DLL, plus un dernier DWORD spécifiant la terminaison de cette DLL.
</p><p>Une troisième structure, IMAGE_IMPORT_BY_NAME, définit le nom des API ainsi que leur numéro ORDINAL (nombre de 16 bits identifiant une fonction au sein d'une DLL). Il en existe autant qu'il y a d'API importées par DLL. Par exemple, sur l'image d'exemple ci-dessus, il y a trois IMAGE_IMPORT_BY_NAME définies pour advapi32.dll, car seulement trois de ses API sont utilisées par le programme.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_IMPORT_DESCRIPTOR</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">_ANONYMOUS_UNION</span><span class="w"> </span><span class="k">union</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Characteristics</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0 for terminating null import descriptor</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">OriginalFirstThunk</span><span class="p">;</span><span class="w"> </span><span class="c1">// It points to the first thunk IMAGE_THUNK_DATA</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="n">DUMMYUNIONNAME</span><span class="p">;</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">TimeDateStamp</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0 if not bound</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">ForwarderChain</span><span class="p">;</span><span class="w"> </span><span class="c1">// -1 if no forwarders</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Name</span><span class="p">;</span><span class="w"> </span><span class="c1">// RVA of DLL Name.</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">FirstThunk</span><span class="p">;</span><span class="w"> </span><span class="c1">// RVA to IAT (if bound this IAT has actual addresses)</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_IMPORT_DESCRIPTOR</span><span class="p">,</span><span class="o">*</span><span class="n">PIMAGE_IMPORT_DESCRIPTOR</span><span class="p">;</span>
</pre></div>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_IMPORT_BY_NAME</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">Hint</span><span class="p">;</span><span class="w"> </span><span class="c1">//Ordinal Number</span>
<span class="w"> </span><span class="n">BYTE</span><span class="w"> </span><span class="n">Name</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span><span class="w"> </span><span class="c1">//Name of function</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_IMPORT_BY_NAME</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_IMPORT_BY_NAME</span><span class="p">;</span>
</pre></div>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">union</span><span class="w"> </span><span class="nc">_IMAGE_THUNK_DATA</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PDWORD</span><span class="w"> </span><span class="n">Function</span><span class="p">;</span>
<span class="w"> </span><span class="n">PIMAGE_IMPORT_BY_NAME</span><span class="w"> </span><span class="n">AddressOfData</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_THUNK_DATA</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_THUNK_DATA</span><span class="p">;</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Table_d'export_-_EAT"><span id="Table_d.27export_-_EAT"></span>Table d'export - EAT</h3></div>
<p>EAT = Export Address Table
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_IMAGE_EXPORT_DIRECTORY</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Characteristics</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x00 */</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">TimeDateStamp</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x04 */</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">MajorVersion</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x08 */</span>
<span class="w"> </span><span class="n">WORD</span><span class="w"> </span><span class="n">MinorVersion</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x0a */</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Name</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x0c */</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">Base</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x10 */</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">NumberOfFunctions</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x14 */</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">NumberOfNames</span><span class="p">;</span><span class="w"> </span><span class="cm">/* 0x18 */</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">AddressOfFunctions</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0x1c RVA from base of image</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">AddressOfNames</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0x20 RVA from base of image</span>
<span class="w"> </span><span class="n">DWORD</span><span class="w"> </span><span class="n">AddressOfNameOrdinals</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0x24 RVA from base of image</span>
<span class="p">}</span><span class="w"> </span><span class="n">IMAGE_EXPORT_DIRECTORY</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">PIMAGE_EXPORT_DIRECTORY</span><span class="p">;</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Le_PE_Loader">Le PE Loader</h2></div>
<p>Le PE Loader est un élément de Windows permettant de reconnaître et de charger en mémoire des fichiers PE. C'est grâce à lui que Windows peut exécuter les instructions d'un tel fichier.
</p>
<ul><li>Voici son fonctionnement global&nbsp;:</li></ul>
<ol><li>Le PE Loader examine l'en-tête MZ afin de trouver l'offset de l'en-tête PE. S'il le trouve il «&nbsp;saute&nbsp;» dessus.</li>
<li>Le PE Loader vérifie la validité de l'en-tête PE. Si tel est le cas il «&nbsp;saute&nbsp;» à la fin de cet en-tête.</li>
<li>Le PE Loader lit les informations concernant les sections puis mappe ces sections en mémoire en employant un procédé de «&nbsp;File Mapping&nbsp;» (copie d'un fichier en mémoire).</li>
<li>Lorsque tout a été <a href="https://fr.wiktionary.org/wiki/mapp%C3%A9" class="extiw external" title="wikt:mappé">mappé</a> en mémoire, le PE Loader se comporte lui-même comme une partie logique du PE File, en tant que table d'importation.</li></ol>
<div class="mw-heading mw-heading2"><h2 id="Reverse_engineering_du_format_PE">Reverse engineering du format PE</h2></div>
<div class="mw-heading mw-heading3"><h3 id="Définition"><span id="D.C3.A9finition"></span>Définition</h3></div>
<p>Le reverse engineering, parfois raccourci en <i>Reversing</i>, est une technique d'analyse logicielle qui permet de trouver des «&nbsp;bugs&nbsp;», des failles, de concevoir des exploits ou des cracks, ou de corriger des problèmes dans un logiciel. Il s'agit d'une technique visant à comprendre le fonctionnement d'un logiciel, sans avoir recours à son <a href="Code_source" title="Code source">code source</a>.
</p><p>Une autre utilisation du Reversing, consiste en l'analyse de <a href="Logiciel_malveillant" title="Logiciel malveillant">Malware</a> dans le but de comprendre son comportement et sa structure, afin de créer un vaccin contre ce dernier. Ces dits vaccins peuvent ensuite être intégrés dans un anti-virus pour protéger le système à l'avenir. À noter que la plupart des virus/anti-virus se concentrent sur Windows, qui est de loin l'OS le plus utilisé/vendu dans le domaine du grand public. Bien qu'il existe des malwares exploitant d'autres infrastructures, comme <a href="Stuxnet" title="Stuxnet">Stuxnet</a>, qui ciblait les systèmes <a href="Syst%C3%A8me_de_contr%C3%B4le_et_d'acquisition_de_donn%C3%A9es" title="Système de contrôle et d'acquisition de données">SCADA</a><sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup>.
</p><p>Cette pratique consiste en une analyse poussée du <a href="Bytecode" title="Bytecode">Bytecode</a> d'un programme (quel qu'en soit le format), pour en révéler son fonctionnement, son comportement. Elle fait ressortir des connaissances poussées du système d'exploitation (<a href="FreeBSD" title="FreeBSD">FreeBSD</a>, <a href="Microsoft_Windows" title="Microsoft Windows">Windows</a>, <a href="Linux" title="Linux">Linux</a>, <a href="Macintosh" title="Macintosh">Mac</a>), de programmation (<a href="ASM_(logiciel)" title="ASM (logiciel)">ASM</a>, <a href="C%2B%2B" title="C++">C/C++</a>), et architecturaux (<a href="X86" title="X86">x86</a>, <a href="Architecture_SPARC" title="Architecture SPARC">SPARC</a>) de la part de celui qui s'y exécute, communément appelé <i>Reverser </i>ou <i>Cracker.</i>
</p><p>Cet article traitant du Format PE (Portable Executable), les informations présentes ici se concentreront donc sur ce format de fichier.
</p><p>Notez qu'il est bien entendu possible d'effectuer toutes les démarches suivantes dans des formats tels que <a href="Executable_and_Linking_Format" class="mw-redirect" title="Executable and Linking Format">ELF</a> (Executable &amp; Linkable Format) ou encore <a href="Mach-O" title="Mach-O">Mach-O</a> (Mach Object File Format). En revanche, en changeant de format, les outils vont changer à leur tour, non pas le principe mais les programmes eux-mêmes&nbsp;; des nuances sur les protections anti-reversing se feront sentir également.
</p>
<div class="mw-heading mw-heading3"><h3 id="Analyse_statique">Analyse statique</h3></div>
<p>Une <i>analyse statique</i> d'un logiciel consiste en une lecture du <a href="Bytecode" title="Bytecode">Bytecode</a> tel qu'il existe sur le <a href="Disque_dur" title="Disque dur">disque dur</a>, c'est-à-dire sans être en exécution.
</p><p>Une lecture du <a href="Bytecode" title="Bytecode">Bytecode</a> d'un programme n'est ni plus ni moins qu'une transformation des suites d'octets présentes dans le programme, en langage <a href="Assembleur" title="Assembleur">ASM</a>, langage <a href="Mn%C3%A9motechnique" title="Mnémotechnique">mnémotechnique</a> permettant une compréhension humaine de ce que doit entreprendre le programme.
</p><p>Des outils ont été spécifiquement développés dans ce but, tels que Win32Dasm, ou Pydasm (<a href="Python_(langage)" title="Python (langage)">Module Python</a>).
</p>
<div class="mw-heading mw-heading3"><h3 id="Analyse_dynamique">Analyse dynamique</h3></div>
<p>Une analyse dynamique comprend deux phases&nbsp;: lecture du code - exécution du code.
</p><p>Pour entreprendre une telle démarche, il est nécessaire de posséder un outil logiciel que l'on nomme <i>Débogueur</i>, tel qu'OllyDbg ou <a href="GNU_Debugger" title="GNU Debugger">GDB</a> (<a href="GNU" title="GNU">GNU</a> Debugger).
</p><p>Le principe étant de <a href="D%C3%A9sassembleur" title="Désassembleur">désassembler</a> le programme tout en l'exécutant, aussi appelé analyse pas à pas ou <i>step-by-step</i>, de manière à pouvoir modifier son comportement en temps réel, afin de comprendre plus en détail son fonctionnement et les modifications possibles.
</p>
<div class="mw-heading mw-heading3"><h3 id="Niveaux_de_privilèges"><span id="Niveaux_de_privil.C3.A8ges"></span>Niveaux de privilèges</h3></div>
<p>La plupart des analyses sont effectués en <b><a href="Anneau_de_protection" title="Anneau de protection">Ring</a></b> 3, c'est-à-dire en <a href="Espace_utilisateur" title="Espace utilisateur">mode utilisateur</a>. Au-dessus on arrive au Ring 0, soit le <a href="Noyau_de_syst%C3%A8me_d'exploitation" title="Noyau de système d'exploitation">Kernel</a>, mais ce genre d'analyse poussé est rare et réservé aux aventuriers (développement de driver, hacking, etc.).
</p><p>Une autre méthode, un peu insolite (mais fonctionnelle) est d'utiliser la <a href="Virtualisation" title="Virtualisation">virtualisation</a> matérielle. Damien Aumaitre a présenté au SSTIC 2010 son outil VirtDbg.
</p><p>Voir <b>(fr)</b> <a rel="nofollow" class="external free" href="http://esec-lab.sogeti.com/dotclear/public/publications/10-sstic-virtdbg_slides.pdf">http://esec-lab.sogeti.com/dotclear/public/publications/10-sstic-virtdbg_slides.pdf</a>
</p><p>Voir <i><a href="Anneau_de_protection" title="Anneau de protection">Anneau de protection</a></i>
</p>
<div class="mw-heading mw-heading3"><h3 id="Protection_anti-reversing">Protection anti-reversing</h3></div>
<p>Le reversing étant vu comme une technique intrusive à l'égard des logiciels <a href="Logiciel_propri%C3%A9taire" title="Logiciel propriétaire">closed-source</a> (Code source propriétaire et non divulgué), les programmeurs ont donc eu l'idée d'inclure des routines spécifiques dans leurs programmes, qui n'auront qu'un unique but&nbsp;: empêcher au maximum la prise d'information sur le comportement du logiciel.
</p><p>Pour ce faire il existe de nombreuses méthodes, dont l'utilisation de Packer (<a href="Chiffrement" title="Chiffrement">chiffrement</a>/compression de code), des codes détecteur de débogueur, insertion de <a href="Somme_de_contr%C3%B4le" title="Somme de contrôle">Checksum</a> etc.
</p>
<div class="mw-heading mw-heading4"><h4 id="Packers">Packers</h4></div>
<p>Un <i>packer</i> est un petit programme dont le but est de <a href="Compression_de_donn%C3%A9es" title="Compression de données">compresser</a> un logiciel afin de réduire sa taille initiale, tout en conservant son aspect exécutable.
</p><p>Néanmoins, avec le temps, de nouveaux packers sont apparus; ces derniers possèdent à présent la capacité de <a href="Cryptographie" title="Cryptographie">chiffrer</a> le code du programme cible, ce qui a pour effet de réduire à la fois son poids et à la fois de modifier son code d'exécution. Un <a href="Algorithme" title="Algorithme">algorithme</a> bien connu, et un des plus simples à contourner puisque la clé est généralement inscrite dans le programme, est sans conteste <a href="XOR" class="mw-redirect" title="XOR">XOR</a> (OU-Exclusif).
</p><p>Bien entendu, la partie liée au déchiffrement - effectuée au lancement du logiciel packé/chiffré - sera effectuée de façon transparente pour l'utilisateur. Mais un reverser verra cela autrement, en visualisant un code ASM différent de la normale.
</p><p><a href="UPX" title="UPX">UPX</a> est un exemple de packer; il permet de réduire de près de 50&nbsp;% la taille d'un exécutable.
</p>
<dl><dd><dl><dd><span class="mw-default-size" typeof="mw:File"></span></dd></dl></dd></dl>
<div class="mw-heading mw-heading4"><h4 id="Détection_de_breakpoint"><span id="D.C3.A9tection_de_breakpoint"></span>Détection de breakpoint</h4></div>
<p>La détection de breakpoint (Point d'Arrêt), consiste à déceler lors de l'exécution d'un binaire l'appel à la fonction INT 3, soit 0xCC en <a href="Syst%C3%A8me_hexad%C3%A9cimal" title="Système hexadécimal">hexadécimal</a>. Un code similaire à celui-ci permettrait d'effectuer cette opération&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="k">if</span><span class="p">(</span><span class="n">byte</span><span class="w"> </span><span class="n">XOR</span><span class="w"> </span><span class="mh">0x55</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mh">0x99</span><span class="p">){</span><span class="w"> </span><span class="c1">// Si Byte = 0xCC -&gt; 0xCC XOR 0x55 == 0x99</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Breakpoint trouvé&nbsp;!!"</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="False_breakpoint">False breakpoint</h4></div>
<p>La technique du <i>false breakpoint</i> consiste à simuler dans le code du logiciel un point d'arrêt comme le ferait un débogueur, grâce à l'instruction INT 3, soit 0xCC en <a href="Syst%C3%A8me_hexad%C3%A9cimal" title="Système hexadécimal">hexadécimal</a>. Lorsqu'un débogueur rencontrera cette fonction, il se stoppera tout seul par la réception d'un signal <i>SIGTRAP</i>.
</p><p>Par défaut, un processus se ferme lorsqu'il reçoit un signal <i>SIGTRAP</i>. L'astuce consiste donc à changer ce comportement par défaut grâce à la fonction signal() appliquée à SIGTRAP.
</p><p>Voici un exemple de code source en langage C, pour les systèmes Linux&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdio.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;signal.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;unistd.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdlib.h&gt;</span>

<span class="kt">void</span><span class="w"> </span><span class="nf">sighandler</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">signal</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Je suis une fonction ordinaire... "</span><span class="p">);</span>
<span class="w"> </span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">signal</span><span class="p">(</span><span class="n">SIGTRAP</span><span class="p">,</span><span class="n">sighandler</span><span class="p">);</span><span class="w"> </span><span class="c1">// On place le sighandler</span>
<span class="w"> </span><span class="n">__asm__</span><span class="p">(</span><span class="s">"int3"</span><span class="p">);</span><span class="w"> </span><span class="c1">// On place un faux Breakpoint</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Pris au piège..."</span><span class="p">);</span><span class="w"> </span><span class="c1">// Le débogueur arrive ici</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">EXIT_FAILURE</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p><br>
</p>
<div class="mw-heading mw-heading4"><h4 id="Détection_de_débogueur"><span id="D.C3.A9tection_de_d.C3.A9bogueur"></span>Détection de débogueur</h4></div>
<p>En pratique, il y a différentes manières de détecter un débogueur.
Le plus simplement possible, avec la fonction <a rel="nofollow" class="external text" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680345(v=vs.85).aspx">IsDebuggerPresent(void)</a> sous Windows&nbsp;:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdio.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;windows.h&gt;</span>

<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="w"> </span><span class="c1">// Attention: cette fonction vaut 0 s'il n'y a pas de débogueur.</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">IsDebuggerPresent</span><span class="p">())</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Helloworld&nbsp;!"</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Debogueur detecte&nbsp;!"</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Ensuite, il existe différentes astuces pour détecter le débogueur.
</p><p>Par exemple:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdio.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;windows.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;time.h&gt;</span>

<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">clock</span><span class="p">();</span>
<span class="w"> </span><span class="n">Sleep</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">DeltaTemps</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">abs</span><span class="p">(</span><span class="n">clock</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">100</span><span class="p">);</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"deltaTemps: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">DeltaTemps</span><span class="p">);</span>

<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">DeltaTemps</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Helloworld&nbsp;!"</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"Debogueur detecte&nbsp;!"</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Ce code calcule une différence de temps. Avec un sleep de 100 ms, normalement la différence est de 100 (à quelques millisecondes près). On calcule donc la différence, on retranche 100 et on obtient un résultat. On applique la fonction abs, pour toujours obtenir une valeur positive. En mode pas-à-pas, le programme sera considérablement ralenti, et ainsi, la différence sera plus élevée et le programme bloquera.
</p>
<div class="mw-heading mw-heading3"><h3 id="Les_outils">Les outils</h3></div>
<ul><li><a rel="nofollow" class="external text" href="http://www.woodmann.com/collaborative/tools/index.php/Category:RCE_Tools">Bibliothèque d'outils pour le Reversing</a></li>
<li><a rel="nofollow" class="external text" href="https://code.google.com/p/pefile/">Module pefile.py</a></li>
<li><a rel="nofollow" class="external text" href="http://dkbza.org/pydasm.html">Module Pydasm.py</a></li>
<li><a rel="nofollow" class="external text" href="http://www.immunityinc.com/products-immdbg.shtml">Immunity Debugger</a></li>
<li><a rel="nofollow" class="external text" href="https://www.aldeid.com/wiki/PEiD">PEiD - Analyse des Packers</a></li>
<li><a rel="nofollow" class="external text" href="http://hackbbs.org/tool/LordPE.html">LordPE - Éditeur de Fichier PE</a></li>
<li><a rel="nofollow" class="external text" href="http://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/WDASM.shtml">W32Dasm - Désassembleur</a></li>
<li><a rel="nofollow" class="external text" href="http://www.ollydbg.de/">OllyDbg - Débogueur pour Windows</a></li>
<li><a rel="nofollow" class="external text" href="http://hackbbs.org/tool/ImpREC.html">ImpRec - Outil de Reconstruction d'IAT</a></li>
<li><a rel="nofollow" class="external text" href="http://angusj.com/resourcehacker/">ResHacker - Éditeur de Ressource</a></li>
<li><a rel="nofollow" class="external text" href="http://www.winhex.com/winhex/">WinHex - Éditeur Hexadécimal</a></li>
<li><a rel="nofollow" class="external text" href="http://www.winitor.com/">PeStudio - Analyse de nombreuses structures PE d'une application</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Voir_aussi">Voir aussi</h2></div>
<ul><li><a href="Executable_and_Linkable_Format" title="Executable and Linkable Format">Format de Fichier Linux (ELF)</a></li>
<li><a href="Mach-O" title="Mach-O">Format de Fichier MAC OS X (Mach-O)</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Liens_externes">Liens externes</h2></div>
<ul><li><a rel="nofollow" class="external text" href="http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx">Microsoft PE &amp; COFF Specification</a></li>
<li><a rel="nofollow" class="external text" href="http://www.openrce.org/reference_library/">PE File Format Diagram</a></li>
<li><a rel="nofollow" class="external text" href="http://www.codeproject.com/dotnet/dotnetformat.asp">The .NET File Format by Daniel Pistelli</a></li>
<li><a rel="nofollow" class="external text" href="http://win32assembly.programminghorizon.com/index.html">Iczelion's Tutorial</a></li>
<li><a rel="nofollow" class="external text" href="http://blog.nibbles.fr/409">Demi-Reversing IAT</a></li>
<li><a rel="nofollow" class="external text" href="ftp://ftp-developpez.com/olance/articles/windows/pe-iczelion/luevelsmeyer.zip">Explication complète sur le Format PE</a></li>
<li><a rel="nofollow" class="external text" href="http://www.ivanlef0u.tuxfamily.org/">Blog d'Ivanlef0u - Hacking under Windows</a></li>
<li><a rel="nofollow" class="external text" href="http://pe101.corkami.com">Visite guidée d'un exécutable Windows</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Notes_et_références"><span id="Notes_et_r.C3.A9f.C3.A9rences"></span>Notes et références</h2></div>
<div class="references-small decimal" style=""><div class="mw-references-wrap"><ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a> </span><span class="reference-text"><span class="ouvrage">«&nbsp;<a rel="nofollow" class="external text" href="http://large.stanford.edu/courses/2015/ph241/holloway1/"><cite style="font-style:normal;">Stuxnet Worm Attack on Iranian Nuclear Facilities</cite></a>&nbsp;», sur <span class="italique">large.stanford.edu</span> <small style="line-height:1em;">(consulté le <time class="nowrap" datetime="2023-02-01" data-sort-value="2023-02-01"><abbr class="abbr" title="premier">1<sup>er</sup></abbr> février 2023</time>)</small></span></span>
</li>
</ol></div>
</div>
<ul id="bandeau-portail" class="bandeau-portail"><li><span class="bandeau-portail-element"><span class="bandeau-portail-icone"><span class="noviewer" typeof="mw:File"></span></span> <span class="bandeau-portail-texte">Portail de Microsoft</span> </span></li> <li><span class="bandeau-portail-element"><span class="bandeau-portail-icone"><span class="noviewer" typeof="mw:File"></span></span> <span class="bandeau-portail-texte">Portail de l’informatique</span> </span></li> </ul></div><!--htdig_noindex--><div><div class="zim-footer">
Cet article est issu de <a class="external text" title="Dernière modification le 2025-03-23" href="https://fr.wikipedia.org/wiki/?title=Portable_Executable&amp;oldid=224155965">Wikipédia</a>. Sauf mention contraire, le texte est disponible sous <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.fr">Creative Commons Attribution-Share Alike 4.0</a>. Des conditions supplémentaires peuvent s’appliquer aux fichiers multimédias.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
<script src="./_webp_/webpHandler.js"></script>

</body></html>